import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { alertContext } from '../contexts/alertContext'
import { copyText } from '../utils'

// 防抖
export function useDebounce(func: any, wait: number, immediate: boolean, callback?: any): (any?: any) => any {
  const timer = useRef<NodeJS.Timeout | null>()
  const fnRef = useRef<any>(func)
  useEffect(() => {
    fnRef.current = func
  }, [func])
  const timerCancel = function () {
    if (timer.current) clearTimeout(timer.current)
  }

  function debounced(...args: any[]) {
    const runFunction = () => {
      return callback ? callback(fnRef.current.apply(fnRef.current, args)) : fnRef.current.apply(fnRef.current, args)
    }
    timerCancel()
    if (immediate) {
      const runNow = !timer.current
      timer.current = setTimeout(() => {
        timer.current = null
      }, wait)
      if (runNow) {
        runFunction()
      }
    } else {
      timer.current = setTimeout(() => {
        runFunction()
      }, wait)
    }
  }
  debounced.cancel = function () {
    timerCancel()
    timer.current = null
  }
  return useCallback(debounced, [wait, immediate, timerCancel, func])
}

export function useHasForm(flow) {
  return useMemo(() => {
    // 如果有 VariableNode  inputnode 就属于
    return !!flow?.data?.nodes.find(node => ['VariableNode', 'InputFileNode'].includes(node.data.type))
  }, [flow])
}

export function useHasReport(flow) {
  return useMemo(() => !!flow?.data?.nodes.find(node => node.data.type === 'Report'), [flow])
}

// 复制文案
export function useCopyText() {
  const { t } = useTranslation()
  const { setSuccessData } = useContext(alertContext)
  return url => {
    copyText(url).then(() => setSuccessData({ title: t('chat.copyTip') }))
  }
}

// 表格通用逻辑（分页展示、表格数据、关键词检索）
export function useTable<T extends object>(param, apiFun, initLoading = false, hasPermission = () => true) {
  const pageSize = param?.pageSize??10
  const [page, setPage] = useState({
    page: 1,
    pageSize: pageSize,
    keyword: ''
  })
  const [total, setTotal] = useState(0)
  const [loading, setLoading] = useState(initLoading)
  const [data, setData] = useState<T[]>([])

  const paramRef = useRef({})

  const requestIdRef = useRef(0) // 控制请求响应顺序
  const loadData = () => {
    // 增加func权限判断
    if (!hasPermission()) {
      return
    }
    setLoading(true)
    const requestId = ++requestIdRef.current
    apiFun({ ...page, ...paramRef.current })
      .then(res => {
        if (requestId !== requestIdRef.current) return
        if (!('total' in res)) return console.error('该接口不支持分页，无法正常使用 useTable')
        setData(res.data)
        setTotal(res.total)
        setLoading(false)
      })
      .catch(() => {
        setLoading(false)
      })
  }
  // const debounceLoad = useDebounce(loadData, 600, false)
  const debounceLoad = useDebounce(loadData, 200, true)

  // 记录旧值
  const prevValueRef = useRef(page)

  useEffect(() => {
    // 排除页码防抖
    prevValueRef.current.page === page.page ? debounceLoad() : loadData()
    prevValueRef.current = page
  }, [page])

  return {
    page: page.page,
    pageSize: page.pageSize,
    total,
    loading,
    data,
    setLoading,
    setPage: p => setPage({ ...page, page: p }),
    reload: debounceLoad,
    // 检索
    search: keyword => {
      setPage({ ...page, page: 1, keyword })
    },
    // 数据过滤
    filterData: p => {
      paramRef.current = { ...paramRef.current, ...p }
      setPage({ ...page, page: 1 })
    },
    // 更新数据
    refreshData: (compareFn, data) => {
      // 乐观更新
      setData(list => {
        return list.map(item => (compareFn(item) ? { ...item, ...data } : item))
      })
    }
  }
}
